#define NOMINMAX
#include "MMOpenMarketOperator.h"

#include <core/StyleMgr.h>
#include <uam/ServerTimeMgr.h>
#include <widgets/SCheckEx.h>
#include <widgets/SImageButton.h>
#include <widgets/STips.h>
#include <widgets/table/STable.h>
#include <widgets/table/STableColumnSet.h>

#include <QColor>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QLabel>
#include <QTableView>
#include <QVBoxLayout>

#include "../FIDataCenter.h"
#include "../StringResource.h"
#include "MMOpenMarketOperatorSettingDlg.h"

namespace {
const int lineHeight = StyleMgr::instance().size("ButtonHeight");
}

MMOpenMarketOperator::MMOpenMarketOperator(QString strTitle, QWidget* parent)
    : SDialog(parent) {
  setTitle(strTitle);

  m_title->setEnableSetting(true);

  QVBoxLayout* layout = qobject_cast<QVBoxLayout*>(this->layout());
  if (!layout) return;
  layout->setContentsMargins(0, 0, 0, 0);
  layout->setSpacing(StyleMgr::instance().size("CtrlSpacing"));
  m_layoutCheckLine = new QHBoxLayout();
  m_chkTodayOnly = new SCheckEx(NewStringTable::strMMOpenMarketOperator(10),
                                this);  // 仅看今日
  m_chkTodayOnly->setFixedHeight(lineHeight);
  m_lblNet = new QLabel(this);
  m_lblNetAmount = new QLabel(this);

  SImageButton* imageTip =
      new SImageButton(this, "widgets_grid_reminder_prompt_c");
  imageTip->setFixedHeight(lineHeight);

  QFont fn = font();
  fn.setBold(true);
  m_lblNetAmount->setFont(fn);
  m_layoutCheckLine->addWidget(m_chkTodayOnly);
  m_layoutCheckLine->addStretch();
  m_layoutCheckLine->addWidget(m_lblNet);
  m_layoutCheckLine->addWidget(m_lblNetAmount);
  m_layoutCheckLine->addWidget(imageTip, 0, Qt::AlignRight | Qt::AlignVCenter);
  m_layoutCheckLine->addSpacing(StyleMgr::instance().size("CtrlSpacing") * 2);
  layout->addLayout(m_layoutCheckLine);

  m_list = new SVirtualTable(this);
  m_model = new DefaultTableModel(this);
  m_model->setTable(m_list);

  layout->addWidget(m_list);

  // QString styleSheet = QString("background-color:#%1")
  //	.arg(StyleMgr::instance().color("BasicPlate").rgb(), 0, 16);
  // setStyleSheet(styleSheet);

  m_list->setHeaderSortable(true);
  m_list->table()->setModel(m_model);
  m_list->table()->horizontalHeader()->setSectionResizeMode(
      QHeaderView::Interactive);
  m_list->table()->horizontalHeader()->setSectionsMovable(true);
  m_list->table()->horizontalHeader()->show();
  m_list->table()->setContextMenuPolicy(Qt::CustomContextMenu);
  initTable();

  connect(imageTip, &SImageButton::enterOrLeaved, this,
          &MMOpenMarketOperator::onShowTips);
  connect(m_chkTodayOnly, &SCheckEx::stateChanged, this,
          &MMOpenMarketOperator::onChkChanged);
  connect(&FIDataCenter::instance(), &FIDataCenter::recvPublicOptionReq, this,
          &MMOpenMarketOperator::onAckDataArrived);
  connect(m_title, &SDialogTitle::setting, this,
          &MMOpenMarketOperator::onSettingClick);

  FIDataCenter::instance().reqPublicOption();
}

bool MMOpenMarketOperator::is_unfold() { return m_list && m_list->isVisible(); }

void MMOpenMarketOperator::fold() {
  if (m_list) {
    for (auto i = 0; i < m_layoutCheckLine->count(); i++) {
      QWidget* w = m_layoutCheckLine->itemAt(i)->widget();
      if (w != nullptr) {
        w->hide();
      }
    }
    m_list->hide();
  }
}

void MMOpenMarketOperator::unfold() {
  if (m_list) {
    for (auto i = 0; i < m_layoutCheckLine->count(); i++) {
      QWidget* w = m_layoutCheckLine->itemAt(i)->widget();
      if (w != nullptr) {
        w->show();
      }
    }
    m_list->show();
  }
}

void MMOpenMarketOperator::initTable() {
#define ALIGN_LEFT (Qt::Alignment)(Qt::AlignVCenter | Qt::AlignLeft)
#define ALIGN_RIGHT (Qt::Alignment)(Qt::AlignVCenter | Qt::AlignRight)

  m_tableSet = new STableColumnSet(m_list, "", this);

  BEGIN_COLUMN;
  ADD_COLUMN(COL_DATE, m_tableSet, NewStringTable::strOMOListHead(COL_DATE), 0, 60, 20,
             0.2, false, ALIGN_LEFT, kAuto, "");
  ADD_COLUMN(COL_TYPE, m_tableSet, NewStringTable::strOMOListHead(COL_TYPE), 0, 60, 20,
             0.2, false, ALIGN_LEFT, kAuto, "");
  ADD_COLUMN(COL_TERM, m_tableSet, NewStringTable::strOMOListHead(COL_TERM), 0, 60, 20,
             0.15, false, ALIGN_LEFT, kAuto, "");
  ADD_COLUMN(COL_RATE, m_tableSet, NewStringTable::strOMOListHead(COL_RATE), 0, 60, 20,
             0.2, false, ALIGN_RIGHT, kAuto, "");
  ADD_COLUMN(COL_AMOUNT, m_tableSet, NewStringTable::strOMOListHead(COL_AMOUNT), 0, 60, 20,
             0.25, false, ALIGN_RIGHT, kAuto, "");
  m_tableSet->apply();

  connect(m_list, &SVirtualTable::viewPosChanged,
          [=](int) { updateTable(false); });

  updateLabel();
  updateTable(true);
}

SDialog* MMOpenMarketOperator::clone(QWidget* parent) {
  MMOpenMarketOperator* pWidget = new MMOpenMarketOperator(m_strTitle, parent);
  return pWidget;
}

void MMOpenMarketOperator::onAckDataArrived() {
  updateLabel();
  updateTable(true);
}

void MMOpenMarketOperator::onChkChanged() { updateTable(true); }

void MMOpenMarketOperator::updateLabel() {
  FIDataCenter::instance().m_dataOMO.calcNetRelease();
  double netRelease = FIDataCenter::instance().m_dataOMO.netRelease(TODAY);
  QString strLabel, strStyle, strValue;
  if (netRelease > 1e-6) {
    strLabel = NewStringTable::strMMOpenMarketOperator(0);
    strStyle =
        QString("QLabel {color:#%1}")
            .arg(StyleMgr::instance().color("Up_Increase_H1").rgb(), 0, 16);
  } else if (netRelease < -1e-6) {
    strLabel = NewStringTable::strMMOpenMarketOperator(1);
    strStyle =
        QString("QLabel {color:#%1}")
            .arg(StyleMgr::instance().color("Down_Reduce_H1").rgb(), 0, 16);
  } else {
    strLabel = NewStringTable::strMMOpenMarketOperator(1);
    strStyle = QString("QLabel {color:#%1}")
                   .arg(StyleMgr::instance().color("Highlight").rgb(), 0, 16);
  }

  strValue = [&]() -> QString {
    QString str = QString::asprintf("%.2f", qAbs(netRelease));
    return str;
  }();

  m_lblNet->setText(strLabel);
  m_lblNetAmount->setText(strValue);
  m_lblNetAmount->setStyleSheet(strStyle);
}

void MMOpenMarketOperator::updateTable(bool reset) {
  SCOPED_MUTEX(FIDataCenter::instance().m_dataOMO.getLock());
  m_list->clearTable();

  QFont f = font();
  f.setPixelSize(13);
  f.setBold(true);

  UINT nToday = ServerTimeMgr::instance().today();
  std::list<xQBAPublicOptionUnit_c>& lstData =
      FIDataCenter::instance().m_dataOMO.m_lstPubOpr;
  int realCount = lstData.size();
  bool showTodayOnly = m_chkTodayOnly->isSelected();
  if (showTodayOnly) {
    realCount = 0;
    for (auto& it : lstData) {
      if (it.m_Date == nToday) realCount++;
    }
  }

  int pageCount = m_list->pageCount();
  pageCount = std::min(pageCount, realCount);
  int pos = reset ? 0 : m_list->sliderPos();
  m_list->setRealDataCount(realCount);

  int colCount = m_model->columnCount();
  int i = 0;
  QString strText;
  for (auto it = lstData.rbegin(); it != lstData.rend(); ++it) {
    if (i < pos) {
      ++i;
      continue;
    }
    int row = i - pos;
    if (row >= pageCount) break;
    xQBAPublicOptionUnit_c& unit = *it;
    if (showTodayOnly && unit.m_Date != nToday) continue;
    for (int col = 0; col < colCount; ++col) {
      if (!m_tableSet->isColVisible(col)) continue;

      QStandardItem* item = m_model->item(row, col);
      if (item == nullptr) item = new QStandardItem();
      item->clearData();
      if (col == COL_DATE) {
        item->setData(StyleMgr::instance().color("TextNormal"),
                      Qt::ForegroundRole);
      } else {
        item->setData(StyleMgr::instance().color("Highlight"),
                      Qt::ForegroundRole);
      }
      item->setData(f, Qt::FontRole);
      QString idStr = QString("%1.%2")
                          .arg(unit.m_Date)
                          .arg(QString::fromLocal8Bit(unit.m_Type));
      item->setData(idStr, DataIdRole);
      switch (col) {
        case COL_DATE:
          if (unit.m_Date == nToday)
            strText = NewStringTable::strMMOpenMarketOperator(100);  // 今日
          else
            strText = QString::asprintf("%04d-%02d-%02d", unit.m_Date / 10000,
                                        (unit.m_Date % 10000) / 100,
                                        unit.m_Date % 100);
          item->setData(strText, Qt::DisplayRole);
          break;
        case COL_TYPE:
          strText = QString::fromLocal8Bit(unit.m_Type);
          item->setData(strText, Qt::DisplayRole);
          item->setData(StyleMgr::instance().color("Highlight"),
                        Qt::ForegroundRole);
          break;
        case COL_TERM:
          strText = QString::fromLocal8Bit(unit.m_TermType);
          item->setData(strText, Qt::DisplayRole);
          item->setData(StyleMgr::instance().color("Highlight"),
                        Qt::ForegroundRole);
          break;
        case COL_RATE:
          if (qAbs(unit.m_Rate) > 1e-6) {
#ifdef WIN32
            if (qstricmp(unit.m_Type_En, "CBS") == 0)
#else
            if (strcasecmp(unit.m_Type_En, "CBS") == 0)
#endif
            {
              strText = NewStringTable::strMMOpenMarketOperator(3).append(
                  QString::asprintf("%.02f", unit.m_Rate));  //(费)
            } else {
              strText = QString::asprintf("%.02f", unit.m_Rate);
            }
          } else {
            strText = "--";
          }
          item->setData(strText, Qt::DisplayRole);
          item->setData(StyleMgr::instance().color("Highlight"),
                        Qt::ForegroundRole);
          item->setData((int)(Qt::AlignRight | Qt::AlignVCenter),
                        Qt::TextAlignmentRole);
          break;
        case COL_AMOUNT:
          if (qAbs(unit.m_Money) > 1e-6) {
            strText = QString::asprintf("%.02f", unit.m_Money);
          } else {
            if (strstr(unit.m_Type_En, "PSL") != NULL ||
                strstr(unit.m_Type_En, "Balance") != NULL)
              strText = "0.00";
            else
              strText = "--";
          }
          item->setData(strText, Qt::DisplayRole);
          item->setData(StyleMgr::instance().color("Highlight"),
                        Qt::ForegroundRole);
          item->setData((int)(Qt::AlignRight | Qt::AlignVCenter),
                        Qt::TextAlignmentRole);
          break;
        default:
          break;
      }
      m_model->setItem(row, col, item);
    }
    ++i;
  }

  {
    std::list<QString>& lstFlash =
        FIDataCenter::instance().m_dataOMO.m_lstFlash;
    if (lstFlash.size() <= 0) return;
    for (auto& it : lstFlash) {
      FlashInfo fi;
      fi.entireRow = true;
      fi.id = it;
      m_list->addFlashInfo(fi, false);
    }
    m_list->startFlash();
  }
}

void MMOpenMarketOperator::onSettingClick() {
  MMOpenMarketOperatorSettingDlg dlg(nullptr);
  connect(&dlg, &MMOpenMarketOperatorSettingDlg::onStateChanged, this,
          &MMOpenMarketOperator::onStateChanged);
  dlg.exec();
}

void MMOpenMarketOperator::onStateChanged() { updateLabel(); }

void MMOpenMarketOperator::onShowTips(bool isShow) {
  if (!isShow) {
    qb::QBTips::hideTip();
    return;
  }

  QString szTips;

  std::vector<qb::QBTipCustomItem> vctCustomItem;
  qb::QBTipCustomItem item;
  item.col = 1;

  for (int i = 0; i < 3; i++) {
    FIDataCenter::instance().m_dataOMO.calcNetRelease();
    double netRelease =
        FIDataCenter::instance().m_dataOMO.netRelease((CashDeliveryType)i);
    QString strLabel, strStyle, strValue;

    int pos = i > 0 ? 4 + i : i;

    if (netRelease > 1e-6) {
      strLabel = NewStringTable::strMMOpenMarketOperator(0 + i + pos);
      item.clrNormal = StyleMgr::instance().color("Up_Increase_H1");
      // strStyle = QString("QLabel
      // {color:#%1}").arg(StyleMgr::instance().color("Up_Increase_H1").rgb(),
      // 0, 16);
    } else if (netRelease < -1e-6) {
      strLabel = NewStringTable::strMMOpenMarketOperator(1 + i + pos);
      item.clrNormal = StyleMgr::instance().color("Down_Reduce_H1");
      // strStyle = QString("QLabel
      // {color:#%1}").arg(StyleMgr::instance().color("Down_Reduce_H1").rgb(),
      // 0, 16);
    } else {
      strLabel = NewStringTable::strMMOpenMarketOperator(1 + i + pos);
      item.clrNormal = StyleMgr::instance().color("Highlight");
      // strStyle = QString("QLabel
      // {color:#%1}").arg(StyleMgr::instance().color("Highlight").rgb(), 0,
      // 16);
    }

    strValue = [&]() -> QString {
      QString str = QString::asprintf("%.2f", qAbs(netRelease));
      return str;
    }();

    item.row = i;
    vctCustomItem.push_back(item);
    szTips.append(QString("%1%2 %3")
                      .arg(i == 0 ? tr("") : tr("\n"))
                      .arg(strLabel)
                      .arg(strValue));
  }

  qb::QBTips::showText(QCursor().pos(), szTips, this, &vctCustomItem);
}
